/*
 * Copyright (c) 2015 Messcat. All rights reserved.
 */
package cc.messcat.common.service;

import cc.messcat.common.dao.BaseDao;
import cc.messcat.common.model.Pager;
import cc.messcat.common.util.BeanUtil;
import cc.messcat.common.util.CollectionUtil;
import cc.messcat.common.util.HQLUtil;
import cc.messcat.common.util.StringUtil;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("baseService")
public class BaseServiceImpl<T> implements BaseService<T> {

	@Autowired
	private BaseDao<T> baseDao;

	@Override
	public <K> K retrieveObject(Class<K> clazz, Long id) {
		return baseDao.get(clazz,id);
	}

	@Override
	public T retrieveObject(Long id) {
		return baseDao.get(id);
	}

	@Override
	public <K> List<K> retrieveAllObjects(Class<K> clazz) {
		return baseDao.getAll(clazz);
	}

	@Override
	public List<T> retrieveAllObjects() {
		return baseDao.getAll();
	}

	@Override
	public void addObject(Object object) {
		baseDao.save(object);
	}

	@Override
	public <K> void modifyObject(K object) {
		baseDao.update(object);
	}

	@Override
	public <K> void removeObject(Class<K> clazz, Long id) {
		baseDao.deleteById(clazz,id);
	}

	@Override
	public void removeObject(Long id) {
		baseDao.deleteById(id);
	}

	@Override
	public <K> void removeObject(K object) {
		baseDao.delete(object);
	}

	@Override
	public <K> List<K> retrieveByExample(K object) {
		return baseDao.findByExample(object);
	}

	@Override
	public Pager<T> retrieveByObject(int pageSize, int pageNo, final Object equalObject, final Object likeObject, String entityName,String orderAttr, String orderType,String orderAttr2, String orderType2 ){
		Map<String, Object> equalMap = new HashMap<>();
		equalMap = BeanUtil.objectToMap(equalMap, equalObject, false, null);

		Map<String, Object> likeMap = new HashMap<>();
		likeMap = BeanUtil.objectToMap(likeMap, likeObject, false, null);

		String hql = HQLUtil.createQueryEqualAndLikeHQL(entityName, equalMap, likeMap);
		if(StringUtil.isNotBlank(orderAttr) && StringUtil.isNotBlank(orderType)){
			String order = " order by o." + orderAttr + " " + orderType;
			hql += order;
			if(StringUtil.isNotBlank(orderAttr2) && StringUtil.isNotBlank(orderType2)){
				String order2 = ",o." + orderAttr + " " + orderType;
				hql += order2;
			}
			hql+=",o.id desc";
		}
		
		return this.baseDao.getPagerByHql(pageNo, pageSize, hql);
	}

	@Override
	public <K> K retrieveObjectByState(Class<K> clazz, Long id) {
		return baseDao.getByState(clazz,id);
	}

	@Override
	public T retrieveObjectByState(Long id) {
		return this.baseDao.getByState(id);
	}

	@Override
	public <K> List<K> retrieveAllObjectByState(Class<K> clazz) {
		return baseDao.getAllByState(clazz);
	}

	@Override
	public List<T> retrieveAllObjectByState() {
		return baseDao.getAllByState();
	}

	@Override
	public void modifyObjectByCondition(String entityName, final Object updateObject, final Object conditionObject){
		Map<String, Object> updateMap = new HashMap<>();
		updateMap = BeanUtil.objectToMap(updateMap, updateObject, false, null);

		Map<String, Object> conditionMap = new HashMap<>();
		conditionMap = BeanUtil.objectToMap(conditionMap, conditionObject, false, null);

		String hql = HQLUtil.createUpdateByConditionHQL(entityName, updateMap, conditionMap);
		this.baseDao.modifyByHql(hql);
	}

	@Override
	public Pager<T> getPager(Integer pageNo, Integer pageSize, List<T> list, Integer rowCount) {
		try {
			checkPageValue(pageNo, pageSize);
		} catch (NullPointerException e) {
			pageNo = 1;
			pageSize = 10;
		}

		if(CollectionUtil.isListEmpty(list)) {
			return new Pager<>(pageSize, pageNo, 0, list);
		} else {
			List<T> resultList = new ArrayList<>();
			if(null != rowCount) {
				rowCount = list.size();
				int fromIndex = (pageNo - 1) * pageSize;
				if(fromIndex >= rowCount) {
					return new Pager<>(pageSize, pageNo, rowCount, resultList);
				}

				int toIndex = fromIndex + pageSize;
				if(toIndex >= rowCount) {
					resultList.addAll(list.subList(fromIndex, rowCount));
				} else {
					resultList.addAll(list.subList(fromIndex, toIndex));
				}
			} else {
				resultList.addAll(list);
			}

			return new Pager<>(pageSize, pageNo, rowCount, resultList);
		}
	}

	private static void checkPageValue(Integer... page) {
		for (Integer no : page) {
			if (null == no || no < 0)
				throw new NullPointerException();
		}
	}

	@Override
	public <K> void modifyObject(K object, Long id)  {
		K object0=retrieveObject((Class<K>) object.getClass(),id);
		try {
			BeanUtil.setBeanByOtherBeanWithoutNull(object0, object);
		} catch (Exception e) {			
			e.printStackTrace();
		}
		baseDao.update(object0);
		
	}

	
}
